package cn.wjc.demo.common.aspect;

import cn.wjc.demo.common.annotation.FileParam;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class FileValidAspect {

    @Pointcut("@annotation(cn.wjc.demo.common.annotation.FileValid)")
    public void pointcut() {

    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) {
        // 参数值
        Object[] args = pjp.getArgs();
        // 方法
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();

        // 参数列表
        Parameter[] mParameters = method.getParameters();
        for (int i = 0; i < mParameters.length; i++) {
            // 判定参数是否有修饰了注解@FileParam
            if (mParameters[i].isAnnotationPresent(FileParam.class)) {
                // 获取注解，进而获得注解中的参数值
                Annotation annotation = mParameters[i].getAnnotation((FileParam.class));
                String[] suffixs = ((FileParam) annotation).suffix();
                int size = ((FileParam) annotation).size();
                log.info("suffixs: {}, size: {}", suffixs, size);
                // 实际文件大小
                long rSize = 0L;
                // 实际文件后缀
                String suffix = null;
                if (args[i] instanceof MultipartFile) {
                    MultipartFile temp = ((MultipartFile) args[i]);
                    rSize = temp.getSize();
                    suffix = temp.getOriginalFilename().split("\\.")[1];
                    log.info("suffix: {}, size: {}", suffix, rSize);
                }

                if (rSize > size) {
                    return String.format("文件大小：%sByte，超过限定大小：%sByte", rSize, size);
                }
                if (!Arrays.asList(suffixs).contains(suffix)) {
                    return String.format("不支持文件上传类型：%s", suffix);
                }

            }
        }

        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return "error";
    }

    @Before("pointcut()")
    public void before() {
        log.info("before...");
    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        log.info("afterReturning...");
    }

    @After("pointcut()")
    public void after() {
        log.info("after ...");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        log.info("afterThrowing ...");
    }
}
